package com.googlecode.framework.orm.ibatis;

import java.sql.SQLException;
import java.util.List;

import org.springframework.orm.ibatis.SqlMapClientCallback;
import org.springframework.orm.ibatis.SqlMapClientTemplate;
import org.springframework.orm.ibatis.support.SqlMapClientDaoSupport;

import com.googlecode.framework.core.pagination.OrderablePagination;
import com.ibatis.sqlmap.client.SqlMapExecutor;

public class DefaultIbatisOrmExecutor extends SqlMapClientDaoSupport implements IbatisOrmExecutor {
    
//    private Logger logger = LoggerFactory.getLogger(getClass());

    @Override
    public <E> E executeForObject(String sqlID, Object bindParams, Class<E> clazz) {
        SqlMapClientTemplate sqlMapTemplate = getSqlMapClientTemplate();
        Object o = sqlMapTemplate.queryForObject(sqlID, bindParams);
        return clazz.cast(o);
    }

    @SuppressWarnings("unchecked")
    @Override
    public <E> List<E> executeForObjectList(String sqlID, Object bindParams) {
        SqlMapClientTemplate sqlMapTemplate = getSqlMapClientTemplate();
        List<E> list = sqlMapTemplate.queryForList(sqlID, bindParams);
        return list;
    }
    
    @SuppressWarnings("unchecked")
    @Override
    public <E> List<E> executeForObjectList(String sqlID, Object bindParams, OrderablePagination op) {
        SqlMapClientTemplate sqlMapTemplate = getSqlMapClientTemplate();
        
        // 如果设置了分页，则统计总数&设置分页条件
        if (op != null) {
            // TODO 如果已经设置过总记录数，则不统计记录数?
            if (op.getItems() <= 0) {
                // 取得总记录数
                Number items = executeForObject("Count(" + sqlID + ")", bindParams, Number.class);
                if (items != null) {
                    op.setItems(items.intValue());
                }
            }
            return sqlMapTemplate.queryForList(sqlID, bindParams, op.getOffset(), op.getLength());
        } else {
            return sqlMapTemplate.queryForList(sqlID, bindParams);
        }
    }

    @Override
    public int executeUpdate(String sqlID, Object bindParams) {
        SqlMapClientTemplate sqlMapTemp = getSqlMapClientTemplate();
        int row = sqlMapTemp.update(sqlID, bindParams);
        return row;
    }

    @Override
    public int executeBatch(final List<SQLHolder> sqlHolders) {
        SqlMapClientTemplate sqlMapTemplate = getSqlMapClientTemplate();
        
        return sqlMapTemplate.execute(new SqlMapClientCallback<Integer>() {
            @Override
            public Integer doInSqlMapClient(SqlMapExecutor executor) throws SQLException {
                executor.startBatch();
                for (SQLHolder sqlHolder : sqlHolders) {
                    executor.update(sqlHolder.getSqlID(), sqlHolder.getBindParams());
                }
                return executor.executeBatch();
            }
        });
    }

    @Override
    public void executeProcedure(String sqlID, Object bindParams) {
        SqlMapClientTemplate sqlMapTemplate = getSqlMapClientTemplate();
        sqlMapTemplate.queryForObject(sqlID, bindParams);
    }

}
